package com.cyf.common.core.thread.executor;

import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author chenyifan
 * @create 2024-08-22 13:14
 */
@Slf4j
public class ExecutorUtil {

    /**
     * 同步执行任务，主线程等待线程池执行完毕
     * @param executor 线程池
     * @param tasks 任务列表
     */
    public static void syncExecute(Executor executor, Runnable... tasks) {
        syncExecute(executor, Arrays.asList(tasks));
    }

    /**
     * 同步执行任务，主线程等待线程池执行完毕
     * @param executor 线程池
     * @param tasks 任务列表
     */
    public static void syncExecute(Executor executor, List<Runnable> tasks) {
        CountDownLatch downLatch = new CountDownLatch(tasks.size());
        for (Runnable task : tasks) {
            executor.execute(() -> {
                try {
                    task.run();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    downLatch.countDown();
                }
            });
        }
        try {
            downLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 统计
     * 任务耗时、初始线程数、核心线程数、
     * 正在执行的任务数量、已完成任务数量、任务总数、队列里缓存的任务数量、
     * 池中存在的最大线程数、最大允许的线程数、
     * 线程空闲时间、线程池是否关闭、线程池是否终止
     * @param executor 线程池
     */
    public void printThreadPoolDetails(ThreadPoolExecutor executor) {
        System.out.println(String.format("线程池大小: %d, 核心线程数: %d, 最大线程数量: %d",
                executor.getPoolSize(), executor.getCorePoolSize(), executor.getMaximumPoolSize()));
        System.out.println(String.format("救急线程存活时间: %d ms", executor.getKeepAliveTime(TimeUnit.MILLISECONDS)));
        System.out.println(String.format("正在执行任务的线程数量: %d", executor.getActiveCount()));
        System.out.println(String.format("任务总数: %d, 已完成任务数量: %d, 未执行的任务数量: %d",
                executor.getTaskCount(), executor.getCompletedTaskCount(), executor.getQueue().size()));
        System.out.println(String.format("线程池是否关闭: %s", executor.isShutdown()));
        System.out.println(String.format("线程池是否终止: %s", executor.isTerminated()));
    }

}
